package com.ruoyi.system.service.impl;

import java.text.DecimalFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson2.JSON;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateTimeUtils;
import com.ruoyi.common.utils.SnowFlakeUtil;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.system.domain.*;
import com.ruoyi.system.domain.params.*;
import com.ruoyi.system.domain.vo.*;
import com.ruoyi.system.mapper.*;
import com.ruoyi.system.service.IUmsCustomerService;
import com.ruoyi.system.service.PrintService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import com.ruoyi.system.service.IWhOrderService;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

/**
 * 客户订单Service业务层处理
 *
 * @author ruoyi
 * @date 2023-02-26
 */
@Slf4j
@Service
public class WhOrderServiceImpl implements IWhOrderService {
    @Resource
    private WhCompanyMapper whCompanyMapper;
    @Resource
    private WhOrderMapper whOrderMapper;
    @Resource
    private UmsCustomerMapper umsCustomerMapper;
    @Resource
    private RedisCache redisCache;
    @Resource
    private SysUserMapper sysUserMapper;
    @Resource
    private IUmsCustomerService customerService;
    @Resource
    private PrintService printService;
    @Resource
    private WhPrintLogMapper whPrintLogMapper;
    @Resource
    private WhPrinterConfigMapper printerConfigMapper;

    public static final String CREATE_ORDER_NO = "create:order:no:%s";

    /**
     * 查询客户订单
     *
     * @param id 客户订单主键
     * @return 客户订单
     */
    @Override
    public WhOrder selectWhOrderById(Integer id) {
        return whOrderMapper.selectWhOrderById(id);
    }

    /**
     * 获取编辑详情
     *
     * @param id
     * @return
     */
    @Override
    public EditOrderInfoVo selectEditOrderById(Integer id) {
        return whOrderMapper.selectEditOrderById(id);
    }

    /**
     * 获取订单详情（常规数据）
     *
     * @param id 订单id
     * @return
     */
    @Override
    public OrderInfoVo getOrderInfoById(Integer id) {
        return whOrderMapper.getOrderInfoById(id);
    }

    /**
     * 查询客户订单列表
     *
     * @param whOrder 客户订单
     * @return 客户订单
     */
    @Override
    public List<OrderListVo> selectWhOrderList(OrderListParams whOrder) {
        List<OrderListVo> orderListVos = whOrderMapper.selectWhOrderList(whOrder);
        if (!CollectionUtil.isEmpty(orderListVos)) {
            for (OrderListVo order : orderListVos) {
                WhPrintLog printInfo = whPrintLogMapper.getOrderPrintUserByOrderId(order.getId());
                if (printInfo != null && StringUtils.isNotEmpty(printInfo.getCreateBy())) {
                    SysUser userInfo = sysUserMapper.selectUserById(Long.parseLong(printInfo.getCreateBy().replaceAll("s_", "")));
                    if (userInfo != null) {
                        order.setPrintName(userInfo.getNickName());
                        order.setPrintAccount(userInfo.getUserName());
                    }
                }
                order.setCustomerName(StringUtils.isEmpty(order.getCustomerName()) ? "未知" : order.getCustomerName());
                if (StringUtils.isNotEmpty(order.getCreateBy())) {
                    if (order.getCreateBy().indexOf("s_") == -1) {
                        order.setCreateBy(order.getCreateBy().equals("0") ? "自主创建" : "未知");
                    } else {
                        SysUser createUser = sysUserMapper.selectUserById(Long.parseLong(order.getCreateBy().replaceAll("s_", "")));
                        order.setCreateBy(createUser == null ? "未知" : createUser.getNickName());
                    }
                }
            }
        }
        return orderListVos;
    }

    /**
     * 新增客户订单
     *
     * @param params 客户订单
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public WhOrder insertWhOrder(SaveOrderParams params) {
        // 校验参数
        boolean verifyParams = StringUtils.isEmpty(params.getGoodsName())
                || StringUtils.isEmpty(params.getArea())
                || StringUtils.isEmpty(params.getWarehousingTime())
                || StringUtils.isEmpty(params.getCustomerName())
                || StringUtils.isEmpty(params.getSellerAddress())
                || StringUtils.isEmpty(params.getSellerPhone())
                || params.getCompanyId() == null;
        if (verifyParams) {
            throw new ServiceException("非法参数");
        }
        WhCompany whCompany = whCompanyMapper.selectWhCompanyById(params.getCompanyId());
        if (whCompany == null) {
            whCompany = new WhCompany();
            whCompany.setOrderPrefix("NULL");
        }
        WhOrder order = new WhOrder();
        // 添加订单数据
        BeanUtils.copyProperties(params, order);
        order.setIsDelete(1);
        order.setStatus(1);
        order.setStatus(1);
        DecimalFormat df = new DecimalFormat("000000");
        Object cacheOrderIndex = redisCache.getCacheObject("create:order:index");
        if (Objects.isNull(cacheOrderIndex)) {
            cacheOrderIndex = 3900;
        } else {
            cacheOrderIndex = Integer.parseInt(cacheOrderIndex.toString()) + 1;
        }
        String orderNo = whCompany.getOrderPrefix() + df.format(Integer.parseInt(Objects.toString(cacheOrderIndex)));
        order.setOrderno(orderNo);
        if (StringUtils.isNotEmpty(params.getWarehousingTime())) {
            order.setWarehousingTime(params.getWarehousingTime());
        } else {
            order.setWarehousingTime(DateTimeUtils.formatDateTimeM(new Date()));
        }
        // 判断客户是否有效
        UmsCustomer orderCustomerInfo = customerService.createOrderCustomerInfo(params);
        order.setCustomId(orderCustomerInfo.getUserId());
        int i = whOrderMapper.insertWhOrder(order);
        if (i == 0) {
            throw new ServiceException("添加订单失败");
        }
        redisCache.setCacheObject("create:order:index", cacheOrderIndex.toString());
        return order;
    }

    /**
     * 修改客户订单
     *
     * @param params 客户订单
     * @return 结果
     */
    @Override
    public int updateWhOrder(SaveOrderParams params) {
        if (params.getId() == null) {
            throw new ServiceException("非法参数");
        }
        EditOrderInfoVo editOrderInfo = whOrderMapper.selectEditOrderById(params.getId());
        if (editOrderInfo == null) {
            throw new ServiceException("订单不存在");
        }
        UmsCustomer orderCustomerInfo = customerService.createOrderCustomerInfo(params);
        params.setCustomerId(orderCustomerInfo.getUserId());
        // 更新参数
        WhOrder order = new WhOrder();
        BeanUtils.copyProperties(params, order);
        if (StringUtils.isNotEmpty(params.getWarehousingTime())) {
            order.setWarehousingTime(params.getWarehousingTime());
        } else {
            order.setWarehousingTime(DateTimeUtils.formatDateTimeM(new Date()));
        }
        order.setCustomId(params.getCustomerId());
        return whOrderMapper.updateWhOrder(order);
    }

    /**
     * 批量删除客户订单
     *
     * @param ids 需要删除的客户订单主键
     * @return 结果
     */
    @Override
    public int deleteWhOrderByIds(Integer[] ids) {
        return whOrderMapper.deleteWhOrderByIds(ids);
    }

    /**
     * 删除客户订单信息
     *
     * @param id 客户订单主键
     * @return 结果
     */
    @Override
    public int deleteWhOrderById(Integer id) {
        return whOrderMapper.deleteWhOrderById(id);
    }

    /**
     * 初始化订单
     *
     * @return
     */
    @Override
    public OrderInitVo initOrder() {
        OrderInitVo orderInitVo = new OrderInitVo();
        orderInitVo.setOrderno(Objects.toString(SnowFlakeUtil.nextId()));
        orderInitVo.setSaveDate(DateTimeUtils.formatDateTimeM(new Date()));
        // 预设订单编号
        redisCache.setCacheObject(
                String.format(CREATE_ORDER_NO, orderInitVo.getOrderno()),
                JSON.toJSONString(orderInitVo),
                60 * 15,
                TimeUnit.SECONDS
        );
        return orderInitVo;
    }

    /**
     * 司机创建订单
     *
     * @param params
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public WhOrder createOrder(CreateOrderParams params) {
        // 校验参数
        boolean verifyParams = StringUtils.isEmpty(params.getOrderno())
                || StringUtils.isEmpty(params.getWarehousingTime())
                || StringUtils.isEmpty(params.getGoodsName())
                || StringUtils.isEmpty(params.getAreaCode())
                || params.getCompanyId() == null
                || StringUtils.isEmpty(params.getCustomCode())
                || StringUtils.isEmpty(params.getCustomName())
                || StringUtils.isEmpty(params.getSellerAddress())
                || StringUtils.isEmpty(params.getSellerPhone());
        if (verifyParams) {
            throw new ServiceException("非法参数");
        }
        UmsCustomer umsCustomer = new UmsCustomer();
        // 如果用户存在就用现有的用户信息
        if (params.getUserId() != null) {
            umsCustomer = umsCustomerMapper.selectUmsCustomerByUserId(params.getUserId());
            if (umsCustomer == null) {
                throw new ServiceException("用户信息异常-1，请刷新后重试！");
            }
        }
        // 否则添加新的用户
        else {
            String cacheValue = redisCache.getCacheObject(String.format(UmsCustomerServiceImpl.USER_NAME_CACHE, params.getCustomName()));
            if (StringUtils.isEmpty(cacheValue)) {
                throw new ServiceException("用户信息异常-2，请刷新后重试！");
            }
            CacheCustomerVo cacheCustomer = JSON.parseObject(cacheValue, CacheCustomerVo.class);
            if (cacheCustomer == null) {
                throw new ServiceException("用户信息异常-3，请刷新后重试！");
            }
            umsCustomer.setCode(cacheCustomer.getCode());
            umsCustomer.setUsername(cacheCustomer.getUsername());
            umsCustomer.setPhone(params.getCustomPhone());
            umsCustomer.setNationality(params.getNationalityId());
            umsCustomer.setCreateBy("0");
            umsCustomer.setCreateTime(new Date());
            BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
            umsCustomer.setPassword(passwordEncoder.encode(cacheCustomer.getPassword()));
            int i = umsCustomerMapper.insertUmsCustomer(umsCustomer);
            if (i == 0) {
                throw new ServiceException("新增客户失败");
            }
        }
        // 判断订单号和时间是否是预设
        if (params.getOrderId() == null) {
            Object orderTempInfo = redisCache.getCacheObject(String.format(CREATE_ORDER_NO, params.getOrderno()));
            if (ObjectUtils.isEmpty(orderTempInfo)) {
                throw new ServiceException("非法订单编码");
            }
            OrderInitVo orderInit = JSON.parseObject(orderTempInfo.toString(), OrderInitVo.class);
            if (ObjectUtils.isEmpty(orderInit)) {
                throw new ServiceException("预存单号不存在");
            }
            if (!orderInit.getSaveDate().equals(params.getWarehousingTime())) {
                throw new ServiceException("预存单号信息错误");
            }
        }
        // 订单数据
        WhOrder order = new WhOrder();
        BeanUtils.copyProperties(params, order);
        order.setOrderno(params.getOrderno());
        order.setCustomId(params.getUserId());
        order.setArea(params.getAreaCode());
        order.setCustomId(umsCustomer.getUserId());
        order.setCreateBy("0");
        order.setCreateTime(new Date());
        int result = 0;
        if (params.getOrderId() == null) {
            result = whOrderMapper.insertWhOrder(order);
            redisCache.deleteObject(String.format(CREATE_ORDER_NO, params.getOrderno()));
        } else {
            order.setId(params.getOrderId());
            order.setUpdateBy(umsCustomer.getUserId() + "");
            order.setUpdateTime(new Date());
            result = whOrderMapper.updateWhOrder(order);
        }
        if (result == 0) {
            throw new ServiceException("添加订单失败");
        }
        return order;
    }

    /**
     * 更新订单信息
     *
     * @param params
     * @return
     */
    @Override
    public int updateOrder(CreateOrderParams params) {
        boolean verifyParams = params.getOrderId() == null
                || params.getUserId() == null;
        if (verifyParams) {
            throw new ServiceException("非法参数");
        }
        UmsCustomer umsCustomer = umsCustomerMapper.selectUmsCustomerByUserId(params.getUserId());
        if (umsCustomer == null) {
            throw new ServiceException("客户不存在");
        }
        WhOrder order = new WhOrder();
        BeanUtils.copyProperties(params, order);
        order.setId(params.getOrderId());
        return whOrderMapper.updateWhOrder(order);
    }

    /**
     * 打印订单 - 支持批量
     *
     * @param ids
     * @return
     */
    @Async
    @Override
    public void printOrder(Integer[] ids, String createBy) {
        for (Integer id : ids) {
            // 预先修改打印订单状态
            WhOrder whOrder = new WhOrder();
            whOrder.setId(id);
            whOrder.setStatus(2);
            int i = whOrderMapper.updateWhOrder(whOrder);
            // 打印订单
            if (i > 0) {
                printService.print(id, createBy, null);
            }
        }
    }

    @Override
    public void printOrderV2(PrinterParam param) {
        WhPrinterConfig whPrinterConfig = printerConfigMapper.selectWhPrinterConfigById(param.getPrinterDeviceId());
        if (whPrinterConfig == null) {
            throw new ServiceException("打印机配置不存在");
        }
        for (Integer id : param.getOrderIds()) {
            // 预先修改打印订单状态
            WhOrder whOrder = new WhOrder();
            whOrder.setId(id);
            whOrder.setStatus(2);
            int i = whOrderMapper.updateWhOrder(whOrder);
            // 打印订单
            if (i > 0) {
                printService.print(id, param.getCreateBy(), whPrinterConfig);
            }
        }
    }

    /**
     * 仓管、财务打单
     *
     * @param params
     */
    @Override
    public void managerPrint(ManagerPrintParams params) {
        boolean verifyParams = params.getOrderId() == null
                || StringUtils.isEmpty(params.getAccount())
                || StringUtils.isEmpty(params.getPassword());
        if (verifyParams) {
            throw new ServiceException("非法参数");
        }
        SysUser userInfo = sysUserMapper.selectUserByUserName(params.getAccount().trim());
        if (userInfo == null) {
            throw new ServiceException("账号或密码错误");
        }
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        if (!passwordEncoder.matches(params.getPassword().trim(), userInfo.getPassword())) {
            throw new ServiceException("账号或密码错误");
        }
        if (!userInfo.getStatus().equals("0")) {
            throw new ServiceException("账号已被停用");
        }
        PrinterParam printerParam = new PrinterParam();
        printerParam.setOrderIds(Collections.singletonList(params.getOrderId()));
        printerParam.setCreateBy(userInfo.getUserId() + "");
        printerParam.setPrinterDeviceId(params.getPrinterDeviceId());
        printOrderV2(printerParam);
    }

    /**
     * 仓管端获取订单列表
     *
     * @param keyword
     * @return
     */
    @Override
    public List<ManagerOrderListVo> findManagerOrderList(String keyword) {
        return whOrderMapper.findManagerOrderList(keyword);
    }
}
